#ifndef __JK_ITERATOR_H_
#define __JK_ITERATOR_H_

#include "jk_base.h"
#include <assert.h>

JK_LIB_NAMESPACE_BEGIN



template <typename ContainerType>
class ForwardIterator
{
public:
    typedef typename ContainerType::value_type           value_type;
    typedef typename ContainerType::value_type&          reference;
    typedef const typename ContainerType::value_type&    const_reference;
    typedef typename ContainerType::value_type*          pointer;
    typedef const typename ContainerType::value_type*    const_pointer;

public:
    ForwardIterator()
        : container_(NULL)
        , curr_(0)
        , end_(0)
    {
    }

    explicit ForwardIterator(ContainerType* container)
        : container_(container)
        , end_(container_->GetNumOfElements())
    {
    }

    ForwardIterator(const ForwardIterator<ContainerType>& it)
        : container_(it.container_)
        , curr_(it.curr_)
        , end_(it.end_)
    {
    }

public:
    bool IsValid()
    {
        return (container_ != NULL && curr_ < end_);
    }

public:
    reference operator*()
    {
        assert(container_ != NULL);
        return (*container_)[curr_];
    }

    ForwardIterator<ContainerType>& operator++()
    {
        assert(container_ != NULL);
        ++curr_;
        return (*this);
    }

    ForwardIterator<ContainerType> operator++(int)
    {
        assert(container_ != NULL);
        ForwardIterator<ContainerType> temp = (*this);
        ++curr_;
        return temp;
    }

    ForwardIterator<ContainerType>& operator=(const ForwardIterator<ContainerType>& it)
    {
        curr_ = it.curr_;
        end_ = it.end_;
        container_ = it->container_;
    }

    bool operator==(const ForwardIterator<ContainerType>& it) const
    {
        return (container_ == it.container_ 
            && curr_ == it.curr_
            && end_ == it.end_);
    }

    bool operator!=(const ForwardIterator<ContainerType>& it) const
    {
        return !((*this) == it);
    }

private:
    int curr_;
    int end_;
    ContainerType* container_;
};


JK_LIB_NAMESPACE_END

#endif //!__JK_ITERATOR_H_
